package cn.hg.solon.youcan.common.util;

import org.dromara.hutool.core.net.url.UrlEncoder;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.StrValidator;
import org.noear.solon.Solon;
import org.noear.solon.core.handle.Context;

/**
 * @author 胡高
 * @date 2022/08/11
 */
public final class RequestUtil {

    static String[] mobileAgents = {"iphone", "android", "phone", "mobile", "wap", "netfront", "java", "opera mobi",
        "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod", "nokia",
        "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma", "docomo",
        "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos", "techfaith",
        "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem", "wellcom", "bunjalloo",
        "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos", "pantech", "gionee", "portalmmm",
        "jig browser", "hiptop", "benq", "haier", "^lct", "320x320", "240x320", "176x220", "w3c ", "acs-", "alav",
        "alca", "amoi", "audi", "avan", "benq", "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-", "dang",
        "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs", "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g",
        "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-", "newt", "noki",
        "oper", "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage", "sams", "sany", "sch-",
        "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem", "smal", "smar", "sony", "sph-", "symb", "t-mo",
        "teli", "tim-", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc",
        "winw", "winw", "xda", "xda-", "googlebot-mobile"};

    public static String getBaseUrl() {
        Context ctx = Context.current();
        return ctx == null ? null : getBaseUrl(ctx);
    }

    public static String getBaseUrl(Context ctx) {
        int port = Solon.cfg().serverPort();
        return StrUtil.builder(128).append(port == 443 ? "https://" : "http://")
            .append(Solon.cfg().serverHost())
            .append(port == 80 || port == 443 ? "" : ":" + port)
            .append(ContextPathUtil.getContextPath()).toString();
    }


    public static String getCurrentEncodeUrl() {
        Context ctx = Context.current();
        return ctx == null ? null : getCurrentEncodeUrl(ctx);
    }

    public static String getCurrentEncodeUrl(Context ctx) {
        return UrlEncoder.encodeAll(getCurrentUrl(ctx));
    }

    public static String getCurrentUrl() {
        Context ctx = Context.current();
        return ctx == null ? null : getCurrentUrl(ctx);
    }


    public static String getCurrentUrl(Context ctx) {
        String queryString = ctx.queryString();
        String url = getBaseUrl(ctx) + ctx.path();
        if (StrValidator.isNotBlank(queryString)) {
            url = url.concat("?").concat(queryString);
        }
        return url;
    }

    public static String getIpAddress(Context ctx) {
        String ip = ctx.header("X-Forwarded-For");
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.header("X-Real-IP");
        }
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.header("Proxy-Client-IP");
        }
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.header("WL-Proxy-Client-IP");
        }
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.header("HTTP_CLIENT_IP");
        }
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.header("HTTP_X_FORWARDED_FOR");
        }
        if (StrValidator.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = ctx.realIp();
        }

        if (ip != null && ip.contains(",")) {
            String[] ips = ip.split(",");
            for (String strIp : ips) {
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }

        return ip;
    }

    public static String getReferer(Context ctx) {
        return ctx.header("Referer");
    }

    public static String getUserAgent(Context ctx) {
        return ctx.header("User-Agent");
    }


    public static boolean isAjaxRequest(Context ctx) {
        String header = ctx.header("X-Requested-With");
        return "XMLHttpRequest".equalsIgnoreCase(header);
    }


    /**
     * 是否是IE浏览器
     *
     * @param ctx
     * @return
     */
    public static boolean isIEBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        if (StrValidator.isBlank(ua)) {
            return false;
        }

        ua = ua.toLowerCase();
        if (ua.indexOf("msie") > -1) {
            return true;
        }

        if (ua.indexOf("gecko") > -1 && ua.indexOf("rv:11") > -1) {
            return true;
        }

        return false;
    }


    public static boolean isJsonContentType(Context ctx) {
        String contentType = ctx.contentType();
        return contentType != null && contentType.toLowerCase().contains("application/json");
    }


    /**
     * 是否是手机浏览器
     *
     * @param ctx
     * @return
     */
    public static boolean isMobileBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        if (StrValidator.isNotBlank(ua)) {
            ua = ua.toLowerCase();
            for (String mobileAgent : mobileAgents) {
                if (ua.indexOf(mobileAgent) > -1) {
                    return true;
                }
            }
        }
        return false;
    }


    public static boolean isMultipartRequest(Context ctx) {
        String contentType = ctx.contentType();
        return contentType != null && contentType.toLowerCase().contains("multipart");
    }


    /**
     * 是否是微信浏览器
     * @param ctx
     * @return
     */
    public static boolean isWechatBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        return StrValidator.isNotBlank(ua) && ua.toLowerCase().indexOf("micromessenger") > -1;
    }

    /**
     * 是否是PC版的微信浏览器
     *
     * @param ctx
     * @return
     */
    public static boolean isWechatPcBrowser(Context ctx) {
        String ua = ctx.header("User-Agent");
        return StrValidator.isNotBlank(ua) && ua.toLowerCase().indexOf("windowswechat") > -1;
    }

}
